import {
  useState,
  useRef,
  memo,
} from 'react'
import classNames from 'classnames'
import {
  RiCloseLine,
  RiVolumeUpLine,
} from '@remixicon/react'
import { useTimeout } from '@/library/hooks/use-timeout'
import { useMutationEffect } from '../../hooks/use-mutation-effect'
import { useResizeEffect } from '../../hooks/use-resize-effect'
import { withNativeProps } from '../../utils/native-props'
import type { NoticeBarProps } from './type'

const classPrefix = 'rt-notice-bar'

export const NoticeBar = memo<NoticeBarProps>((props) => {
  const {
    closeable,
    content,
    delay = 2000,
    extra,
    icon = <RiVolumeUpLine size={20} />,
    onClick,
    onClose,
    speed = 50,
    type = 'default',
    wrap = false,
  } = props

  const containerRef = useRef<HTMLSpanElement>(null)
  const textRef = useRef<HTMLSpanElement>(null)

  const delayLockRef = useRef<boolean>(true)
  const animatingRef = useRef<boolean>(false)

  const [visible, setVisible] = useState(true)

  const start = () => {
    if (delayLockRef.current || wrap) return

    const container = containerRef.current
    const text = textRef.current
    if (!container || !text) return

    if (container.offsetWidth >= text.offsetWidth) {
      animatingRef.current = false
      text.style.removeProperty('transition-duration')
      text.style.removeProperty('transform')
      return
    }

    if (animatingRef.current) return

    const initial = !text.style.transform
    text.style.transitionDuration = '0s'
    if (initial) {
      text.style.transform = 'translateX(0)'
    } else {
      text.style.transform = `translateX(${container.offsetWidth}px)`
    }

    const distance = initial
      ? text.offsetWidth
      : container.offsetWidth + text.offsetWidth

    animatingRef.current = true
    text.style.transitionDuration = `${Math.round(distance / speed)}s`
    text.style.transform = `translateX(-${text.offsetWidth}px)`
  }

  useTimeout(() => {
    delayLockRef.current = false
    start()
  }, delay)

  useResizeEffect(() => {
    start()
  }, containerRef)

  useMutationEffect(
    () => {
      start()
    },
    textRef,
    {
      subtree: true,
      childList: true,
      characterData: true,
    },
  )

  if (!visible) return null

  return (
    withNativeProps(
      props,
      <div
        className={classNames(classPrefix, `${classPrefix}-${type}`, {
          [`${classPrefix}-wrap`]: wrap,
        })}
        onClick={onClick}
      >
        {icon && (
          <span className={`${classPrefix}-left`}>{icon}</span>
        )}
        <span ref={containerRef} className={`${classPrefix}-content`}>
          <span
            className={`${classPrefix}-content-inner`}
            ref={textRef}
            onTransitionEnd={() => {
              // 无限循环
              animatingRef.current = false
              start()
            }}
          >
            {content}
          </span>
        </span>
        {
          (closeable || extra) && (
            <span className={`${classPrefix}-right`}>
              {extra}
              {closeable && (
                <div
                  className={`${classPrefix}-close`}
                  onClick={() => {
                    setVisible(false)
                    onClose?.()
                  }}
                >
                  <RiCloseLine size={20} />
                </div>
              )}
            </span>
          )
        }
      </div>,
    )
  )
})
